<?php

/*
 * Used Peter's Collaboration E-mails (1.6.2) and Peter's Post Notes (1.3.1) to generate this code
 * Peter's Collaboration E-mails URI: http://www.theblog.ca/wordpress-collaboration-emails
 * Peter's Post Notes URI: http://www.theblog.ca/wordpress-post-notes
 * Original author: Peter Keung @ http://www.theblog.ca/
 * Edited by: Rollins 2012 CMS capstone
 * 
 * This code is not supported by the original author. It cannot be updated to any future versions.
 * The original plugins have been combined and altered to best fit ACCS and will not work as a seperate plugin.
 * 
 * Do not alter the database names unless the changes are reflected in the core plugin under the activate function.
 */

global $wpdb;
global $accs_notification_db_group, $accs_notification_db_collabrules;

// ------------------------------
// This section may be modified
// ------------------------------

// The URL to your site. Replace this with the base WordPress directory (containing the wp-admin folder) if the pending e-mail notification does not have the correct URL
$accs_notification_siteurl = get_option('siteurl');

// The name of your blog, to appear in the title of e-mails. Replace this if e-mail subjects aren't correct
$accs_notification_blogname = get_option('blogname');

// Set this value to true if you want the contributor to know who approved his / her post.
$accs_notification_whoapproved = true;

// Which roles on your site can approve posts
// Typically you do not have to edit this unless you have custom roles and capabilities
$accs_notification_moderator_roles = array();
$accs_notification_moderator_roles[] = 'administrator';
$accs_notification_moderator_roles[] = 'editor';

// Which e-mails to send. Set any of these to false to disable them
$accs_notification_emails_to_send = array();
// Set to pending for the first time
$accs_notification_emails_to_send['pending'] = true;
// Goes from pending to immediately published
$accs_notification_emails_to_send['approved'] = true;
// Goes from pending to approved at a set time in the future
$accs_notification_emails_to_send['future'] = true;
// Goes back to draft status
$accs_notification_emails_to_send['backtodraft'] = true;
// Goes from scheduled to be published to actually published
$accs_notification_emails_to_send['wentlive'] = true;
// Goes from pending, draft, or published to trashed
$accs_notification_emails_to_send['denied'] = true;
// Goes no state change but a note is included
$accs_notification_emails_to_send['note'] = true;

// To edit the notification e-mail settings in the WordPress admin panel, users need this capability
// Typically editors and up have "manage_links" capabilities
// See http://codex.wordpress.org/Roles_and_Capabilities for more information about out of the box capabilities
$accs_notification_required_capability = 'manage_links';


// List of post types on which the post notes should be enabled
$accs_note_post_types = array();
//$accs_note_post_types[] = 'page';
$accs_note_post_types[] = 'accs_event';
$accs_note_post_types[] = 'accs_promo';
$accs_note_post_types[] = 'accs_announcement';

//----------------------------------------------------------------------------------------------------
// Only change the database names if the main plugin reflects the name changes (in activate function).
//----------------------------------------------------------------------------------------------------

// Name of the database table that will hold group information and moderator rules
$accs_notification_db_group = $wpdb->prefix . 'collaboration';
// Name of the database table that will hold post-type-specific moderators
$accs_notification_db_collabrules = $wpdb->prefix . 'collabrules';

// -------------------------------------------
// You should not have to edit below this line
// There is some unused code for notes being sent with trashing posts that would never work. Feel free to try to make it work, its at the bottom of the accs_notification_pending function
// -------------------------------------------

// Call jQuery
function accs_notification_js_admin_header()
{
    wp_enqueue_script( 'jquery' );
}

function accs_notification_pending($accs_notification_newstatus, $accs_notification_oldstatus, $accs_notification_object)
{
    global $accs_notification_siteurl, $accs_notification_blogname, $accs_saved_note, $accs_notification_fromname, $accs_notification_fromaddress, $accs_notification_whoapproved, $accs_notification_emails_to_send, $user_identity, $user_email, $_POST;

    // The person who wrote the post
    $accs_notification_thisuser = get_userdata($accs_notification_object->post_author);

    // Get information about the currently logged in user, as the person submitting the post for review or approving it
    // Their name is mapped to $user_identity and their e-mail address is mapped to $user_email
    get_currentuserinfo();

    // If specified in the settings, assign the current user values as the e-mail sender information
    $accs_notification_fromname = $user_identity;
    $accs_notification_fromaddress = $user_email;

    // Line break, which we will use many times in constructing e-mails
    $accs_notification_eol = "\r\n";
    
    refresh_note();
    
    // Make sure the mail client knows it's a UTF-8 e-mail
    $accs_notification_headers = 'Content-Type: text/plain; charset=utf-8' . $accs_notification_eol;

    // E-mail moderator(s) for pending posts
    if( $accs_notification_emails_to_send['pending'] && 'pending' == $accs_notification_newstatus && 'pending' != $accs_notification_oldstatus )
    {

        $accs_notification_moderator = accs_notification_gen_moderator_list_email();

        // Header stuff for a pending post
        // Header stuff from http://ca.php.net/mail
        $accs_notification_headers .= 'From:' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>'. $accs_notification_eol;
        $accs_notification_headers .= 'Reply-To:' . $accs_notification_fromname . ' <'. $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Return-Path:' . $accs_notification_fromname . ' <'. $accs_notification_fromaddress . '>' . $accs_notification_eol;

        // Body of the e-mail for a pending post
        $accs_notification_body = sprintf('There is a new post to review, written by %s.', $accs_notification_fromname) . $accs_notification_eol . $accs_notification_eol;
        // Insert note if applicable
        if(isset($accs_saved_note)) {
            $accs_notification_body .= sprintf('Accompanying note from %s:', $accs_notification_fromname) . $accs_notification_eol;
            $accs_notification_body .= $accs_saved_note . $accs_notification_eol . $accs_notification_eol;
        }
        $accs_notification_body .= 'Review and publish it here: ' . $accs_notification_siteurl . '/wp-admin/post.php?action=edit&post=' . $accs_notification_object->ID;

        // E-mail subject for a pending post
        $accs_notification_subject = '[' . $accs_notification_blogname . '] "' . $accs_notification_object->post_title . '" ' . 'pending';

        // Send the notification e-mail for a pending post
        wp_mail($accs_notification_moderator, $accs_notification_subject, $accs_notification_body, $accs_notification_headers);
    }

    // E-mail the post author when a post is approved
    elseif( $accs_notification_emails_to_send['approved'] && 'pending' == $accs_notification_oldstatus && 'publish' == $accs_notification_newstatus )
    {

        // Header stuff for an approved post
        // Header stuff from http://ca.php.net/mail
        $accs_notification_headers .= 'From: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Reply-To: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Return-Path: ' . $accs_notification_fromname. ' <' . $accs_notification_fromaddress .'>' . $accs_notification_eol;

        // E-mail body for an approved post
        $accs_notification_body = sprintf( 'Hi %s!', $accs_notification_thisuser->display_name ) . $accs_notification_eol . $accs_notification_eol;
        if( $accs_notification_whoapproved )
        {
            $accs_notification_body .= sprintf( 'Your post has been approved by %s and is now published', $accs_notification_fromname );
        }
        else
        {
            $accs_notification_body .= 'Your post has been approved';
        }
        
        $accs_notification_body .= $accs_notification_eol . $accs_notification_eol;
        
        // Insert note if applicable
        if(isset($accs_saved_note)) {
            $accs_notification_body .= 'Accompanying note:' . $accs_notification_eol;
            $accs_notification_body .= $accs_saved_note . $accs_notification_eol . $accs_notification_eol;
        }
        $accs_notification_body .= 'See it here:' . ' ' . get_permalink($accs_notification_object->ID);

        // E-mail subject for an approved post
        $accs_notification_subject = '[' . $accs_notification_blogname . '] "' . $accs_notification_object->post_title . '" ' . 'published';

        // Send the notification e-mail for an approved post
        wp_mail($accs_notification_thisuser->user_email, $accs_notification_subject, $accs_notification_body, $accs_notification_headers);
    }

    
    // E-mail the post author when a post is scheduled to be published
    elseif( $accs_notification_emails_to_send['future'] && 'pending' == $accs_notification_oldstatus && 'future' == $accs_notification_newstatus )
    {

        // Header stuff for an approved post
        // Header stuff from http://ca.php.net/mail
        $accs_notification_headers .= 'From: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Reply-To: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Return-Path: ' . $accs_notification_fromname. ' <' . $accs_notification_fromaddress .'>' . $accs_notification_eol;

        // E-mail body for a scheduled post
        $accs_notification_body = sprintf('Hi %s!', $accs_notification_thisuser->display_name) . $accs_notification_eol . $accs_notification_eol;
        if( $accs_notification_whoapproved )
        {
            $accs_notification_body .= sprintf( 'Your post has been approved by %s and is scheduled to be published on %s', $accs_notification_fromname, $accs_notification_object->post_date);
        }
        else
        {
            $accs_notification_body .= sprintf( 'Your post has been approved and is scheduled to be published on %s', $accs_notification_object->post_date);
        }
        $accs_notification_body .= $accs_notification_eol . $accs_notification_eol;

        // Insert note if applicable
        if(isset($accs_saved_note)) {
            $accs_notification_body .= 'Accompanying note:' . $accs_notification_eol;
            $accs_notification_body .= $accs_saved_note . $accs_notification_eol . $accs_notification_eol;
        }

        // E-mail subject for an approved post
        $accs_notification_subject = '[' . $accs_notification_blogname . '] "' . $accs_notification_object->post_title . '" ' . 'approved and scheduled';

        // Send the notification e-mail for an approved post
        wp_mail($accs_notification_thisuser->user_email, $accs_notification_subject, $accs_notification_body, $accs_notification_headers);
    }

    
    // E-mail the post author if their post is back to draft status
    elseif( $accs_notification_emails_to_send['backtodraft'] && 'pending' == $accs_notification_oldstatus && 'draft' == $accs_notification_newstatus )
    {
        // E-mail the post author to let them know that their post has been published

        // Header stuff for a "back to draft" post
        // Header stuff from http://ca.php.net/mail
        $accs_notification_headers .= 'From: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Reply-To: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Return-Path: ' . $accs_notification_fromname. ' <' . $accs_notification_fromaddress .'>' . $accs_notification_eol;

        // E-mail body for a "back to draft" post
        $accs_notification_body = sprintf('Hi %s!', $accs_notification_thisuser->display_name) . $accs_notification_eol . $accs_notification_eol;
        if( $accs_notification_whoapproved )
        {
            $accs_notification_body .= sprintf( 'Your post has been reverted back to draft status by %s.', $accs_notification_fromname );
        }
        else
        {
            $accs_notification_body .= 'Your post has been reverted back to draft status.';
        }
        
        $accs_notification_body .= $accs_notification_eol . $accs_notification_eol;
        
        if(isset($accs_saved_note)) {
            $accs_notification_body .= 'Accompanying note:' . $accs_notification_eol;
            $accs_notification_body .= $accs_saved_note . $accs_notification_eol . $accs_notification_eol;
        }
        
        $accs_notification_body .= 'Edit it again here:' . ' ' . $accs_notification_siteurl . '/wp-admin/post.php?action=edit&post=' . $accs_notification_object->ID;

        // E-mail subject for a "back to draft" post
        $accs_notification_subject = '[' . $accs_notification_blogname . '] "' . $accs_notification_object->post_title . '" ' . 'back to draft';

        // Send the notification e-mail for a "back to draft" post
        wp_mail($accs_notification_thisuser->user_email, $accs_notification_subject, $accs_notification_body, $accs_notification_headers);
    }

    
    // E-mail author when his/her scheduled post is published
    elseif( $accs_notification_emails_to_send['wentlive'] && 'future' == $accs_notification_oldstatus && 'publish' == $accs_notification_newstatus )
    {

        $accs_notification_fromaddress = get_option('admin_email');

        // Header stuff for a pending post
        // Header stuff from http://ca.php.net/mail
        $accs_notification_headers .= 'From: ' . $accs_notification_blogname . ' <' . $accs_notification_fromaddress . '>'. $accs_notification_eol;
        $accs_notification_headers .= 'Reply-To: ' . $accs_notification_blogname . ' <'. $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Return-Path: ' . $accs_notification_blogname . ' <'. $accs_notification_fromaddress . '>' . $accs_notification_eol;

        // Body of the e-mail for a previously-scheduled, now published post
        $accs_notification_body = sprintf('Hi %s!', $accs_notification_thisuser->display_name) . $accs_notification_eol . $accs_notification_eol;
        $accs_notification_body .= 'Your post is now live.' . $accs_notification_eol . $accs_notification_eol;
        $accs_notification_body .= 'See it here:' . ' ' . get_permalink($accs_notification_object->ID);

        // E-mail subject for a previously-scheduled, now published post
        $accs_notification_subject = '[' . $accs_notification_blogname . '] "' . $accs_notification_object->post_title . '" ' . 'is now live';
        
        // Send the notification e-mail for a previously-scheduled, now published post
        wp_mail($accs_notification_thisuser->user_email, $accs_notification_subject, $accs_notification_body, $accs_notification_headers);
    }

    // E-mail the post author if their post is trashed
    elseif( $accs_notification_emails_to_send['denied'] && ('pending' == $accs_notification_oldstatus || 'draft' == $accs_notification_oldstatus || 'publish' == $accs_notification_oldstatus) && 'trash' == $accs_notification_newstatus )
    {
        if ($accs_notification_thisuser->display_name != $accs_notification_fromname){
            // Header stuff for a "trashed" post
            // Header stuff from http://ca.php.net/mail
            $accs_notification_headers .= 'From: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
            $accs_notification_headers .= 'Reply-To: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
            $accs_notification_headers .= 'Return-Path: ' . $accs_notification_fromname. ' <' . $accs_notification_fromaddress .'>' . $accs_notification_eol;

            // E-mail body for a "trashed" post
            $accs_notification_body = sprintf('Hi %s!', $accs_notification_thisuser->display_name) . $accs_notification_eol . $accs_notification_eol;
            if( $accs_notification_whoapproved )
            {
                $accs_notification_body .= sprintf( 'Your post has been trashed by %s.', $accs_notification_fromname );
            }
            else
            {
                $accs_notification_body .= 'Your post has been trashed.';
            }

            $accs_notification_body .= $accs_notification_eol . $accs_notification_eol;
            /*
            if(isset($accs_saved_note)) {
                $accs_notification_body .= 'Reason for denial:' . $accs_notification_eol;
                $accs_notification_body .= $accs_saved_note . $accs_notification_eol . $accs_notification_eol;
            }
            */
            // E-mail subject for a "trashed" post
            $accs_notification_subject = '[' . $accs_notification_blogname . '] "' . $accs_notification_object->post_title . '" ' . 'denied';

            // Send the notification e-mail for a "trashed" post
            wp_mail($accs_notification_thisuser->user_email, $accs_notification_subject, $accs_notification_body, $accs_notification_headers);
        }
      
    }
    
    //Email appropriate person if there is no status change and a note is included
    elseif( $accs_notification_emails_to_send['note'] && $accs_notification_oldstatus ==  $accs_notification_newstatus && isset($accs_saved_note))
    {
        $accs_receive = $accs_notification_thisuser->user_email;
        
        // Header stuff for a post with a note
        // Header stuff from http://ca.php.net/mail
        $accs_notification_headers .= 'From: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Reply-To: ' . $accs_notification_fromname . ' <' . $accs_notification_fromaddress . '>' . $accs_notification_eol;
        $accs_notification_headers .= 'Return-Path: ' . $accs_notification_fromname. ' <' . $accs_notification_fromaddress .'>' . $accs_notification_eol;
        
        if ($accs_notification_thisuser->display_name != $accs_notification_fromname)
            $accs_notification_body = sprintf('Hi %s!', $accs_notification_thisuser->display_name) . $accs_notification_eol . $accs_notification_eol;
        elseif ($accs_notification_thisuser->display_name == $accs_notification_fromname)
            $accs_receive = accs_notification_gen_moderator_list_email();
        
        $accs_notification_body .= 'Follow up note:' . $accs_notification_eol;
        $accs_notification_body .= $accs_saved_note . $accs_notification_eol . $accs_notification_eol;
        
        if ($accs_notification_newstatus == 'publish')
            $accs_notification_body .= 'See it here:' . ' ' . get_permalink($accs_notification_object->ID);
        else
            $accs_notification_body .= 'See it here:' . ' ' . $accs_notification_siteurl . '/wp-admin/post.php?action=edit&post=' . $accs_notification_object->ID;

        // E-mail subject for a post with included note
        $accs_notification_subject = '[' . $accs_notification_blogname . '] "' . $accs_notification_object->post_title . '" ' . 'update';

        // Send the notification e-mail for a post with a note
        wp_mail($accs_receive, $accs_notification_subject, $accs_notification_body, $accs_notification_headers);
    }
}

/**
 * Generates the moderator list for emailing purposes
 * 
 * @global type $wpdb
 * @global string $accs_notification_db_group
 * @return string $mod_list
 */
function accs_notification_gen_moderator_list_email()
{
    global $wpdb, $accs_notification_db_group;
    $mod_list = '';
    $accs_notification_moderators_unserialized = array();

    // Get post type rules
    $accs_notification_moderators = accs_notification_get_post_type_moderators( $accs_notification_object );

    if( count( $accs_notification_moderators ) )
    {
        foreach( $accs_notification_moderators as $accs_notification_moderator )
            $accs_notification_moderators_unserialized = array_merge( unserialize( $accs_notification_moderator ), $accs_notification_moderators_unserialized );
    }


    // Remove duplicate entries for groups and categories
    $accs_notification_moderators_unserialized = array_unique($accs_notification_moderators_unserialized);

    // Get the default moderator information
    if (count($accs_notification_moderators_unserialized) == 0)
    {
        $accs_notification_moderators = $wpdb->get_var('SELECT moderators FROM ' . $accs_notification_db_group . ' WHERE collabgroup = 1');
        $accs_notification_moderators_unserialized = unserialize($accs_notification_moderators);
    }
    $accs_notification_moderators_emails = array();

    foreach ($accs_notification_moderators_unserialized as $accs_notification_moderator_unserialized)
    {
        if (is_numeric($accs_notification_moderator_unserialized))
        {
            $accs_notification_moderator_data = get_userdata($accs_notification_moderator_unserialized);
            $accs_notification_moderators_emails[] = $accs_notification_moderator_data->user_email;
        }
        elseif($accs_notification_moderator_unserialized == 'admin')
            $accs_notification_moderators_emails[] = get_option('admin_email');
        // must be an e-mail address
        else
            $accs_notification_moderators_emails[] = $accs_notification_moderator_unserialized;
    }

    // Remove duplicate entries after converting to e-mail addresses
    $accs_notification_moderators_emails = array_unique($accs_notification_moderators_emails);

    $mod_list = implode (', ', $accs_notification_moderators_emails);
    return $mod_list;
}

function accs_notification_get_post_type_moderators( $post_object )
{
    global $wpdb, $accs_notification_db_collabrules;

    $post_type_moderators = array();

    // Get this post's taxonomies
    // First, find out its post type
    // If post type is a revision, fetch the post's parent
    if( 'revision' == $post_object->post_type )
    {
        $post_object = get_post( $post_object->post_parent );
    }
    
    // Get moderators for $post_object->post_type
    $post_type_rules = $wpdb->get_results( 'SELECT taxonomy, term, moderators FROM ' . $accs_notification_db_collabrules . ' WHERE post_type = \'' . $post_object->post_type . '\'', OBJECT );

    if( $post_type_rules )
    {
        // Prepare the list of moderator rules for this post type in an easily accessible PHP variable
        $post_type_moderator_rules = array();
        foreach( $post_type_rules as $post_type_rule )
        {
            $term = strtolower( $post_type_rule->term );
            if( isset( $post_type_moderator_rules[$post_type_rule->taxonomy] ) )
            {
                $post_type_moderator_rules[$post_type_rule->taxonomy][$term] = $post_type_rule->moderators;
                // Store the term as its name as well
                // This is because they're submitted as their name or ID (in the case of categories)
                // We're also storing them as their ID if they exist
                if( is_numeric( $post_type_rule->term ) )
                {
                    $term_object = get_term( $post_type_rule->term, $post_type_rule->taxonomy );
                    if( $term_object )
                    {
                        $term = strtolower( $term_object->name );
                        $post_type_moderator_rules[$post_type_rule->taxonomy][$term] = $post_type_rule->moderators;
                    }
                }
            }
            else
            {
                $post_type_moderator_rules[$post_type_rule->taxonomy] = array( $term => $post_type_rule->moderators );
                // Same as above regarding term name and ID
                if( is_numeric( $post_type_rule->term ) )
                {
                    $term_object = get_term( $post_type_rule->term, $post_type_rule->taxonomy );
                    if( $term_object )
                    {
                        $term = strtolower( $term_object->name );
                        $post_type_moderator_rules[$post_type_rule->taxonomy][$term] = $post_type_rule->moderators;
                    }
                }
            }
        }
        // Loop through the categories
        if( isset( $_POST['post_category'] ) )
        {
            $post_categories = $_POST['post_category'];
            if( 0 == count( $post_categories ) || ! is_array( $post_categories) )
            {
                $post_categories = array( get_option( 'default_category' ) );
            }
            foreach( $post_categories as $post_category )
            {
                if( isset( $post_type_moderator_rules['category'][$post_category] ) )
                {
                    $post_type_moderators[] = $post_type_moderator_rules['category'][$post_category];
                }
            }
        }
        
        // Loop through all taxonomies
        if( isset( $_POST['tax_input'] ) )
        {
            $post_taxonomies = $_POST['tax_input'];
            foreach( $post_taxonomies as $taxonomy => $term_list )
            {
                // In editor mode, terms are either in an array checkbox (like categories) or freeform listed, comma-separated (like tags)
                if( is_array( $term_list ) )
                {
                    $terms = $term_list;
                }
                else
                {
                    $terms = explode( ',', $term_list );
                }
                if( $terms )
                {
                    foreach( $terms as $term )
                    {
                        $term = strtolower( trim( $term ) );
                        if( isset( $post_type_moderator_rules[$taxonomy][$term] ) )
                        {
                            $post_type_moderators[] = $post_type_moderator_rules[$taxonomy][$term];
                        }
                    }
                }
            }
            
        }
        // Add moderators for "all" taxonomies
        if( isset( $post_type_moderator_rules['all'] ) )
        {
            $post_type_moderators[] = $post_type_moderator_rules['all'][''];
        }
    }
    return $post_type_moderators;
}

if( is_admin() ) { // This line makes sure that all of this code below only runs if someone is in the WordPress back-end

// This generates an option of checkbox output for contributors or editors and administrators in the system, as well as an "admin" and "other" choice
function accs_notification_usersoptions( $accs_notification_existingmoderators = array())
{
    global $wpdb, $accs_notification_moderator_roles, $accs_notification_moderatorcache;

    $accs_notification_usersoptions = '';
    
    // Build SQL query portion to filter contributors or approvers
    $accs_notification_contrib_approve_code = '';
    $accs_notification_filter_roles = $accs_notification_moderator_roles;
    $delimiter = '';
    
    foreach( $accs_notification_filter_roles as $accs_notification_filter_role )
    {
        $accs_notification_contrib_approve_code .= $delimiter;
        $accs_notification_contrib_approve_code .= "'%" . $accs_notification_filter_role . "%'";
        $delimiter = ' OR ' . $wpdb->usermeta . '.meta_value LIKE ';
    }
    
    if (isset($accs_notification_moderatorcache)) {
        $accs_notification_userresults = $accs_notification_moderatorcache;
    }
    else {
        $accs_notification_userresults = $wpdb->get_results("SELECT ID, $wpdb->users.display_name, $wpdb->users.user_email FROM $wpdb->users, $wpdb->usermeta WHERE $wpdb->users.ID = $wpdb->usermeta.user_id AND $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND ($wpdb->usermeta.meta_value LIKE " . $accs_notification_contrib_approve_code . ") ORDER BY $wpdb->users.display_name", ARRAY_N);
    }
    if ($accs_notification_userresults) {
        $i = 0;
        foreach ($accs_notification_userresults as $accs_notification_userresult) {
            if (isset($accs_notification_existingmoderators[$accs_notification_userresult[0]])) continue;
            $accs_notification_usersoptions .= "\n" . '                    <option value="' . $accs_notification_userresult[0] . '">' . $accs_notification_userresult[1] . ' (' . $accs_notification_userresult[2] . ')</option>';
            ++$i;
        }
    }
    $accs_notification_moderatorcache = $accs_notification_userresults;

    if (!isset($accs_notification_existingmoderators['admin']))
    {
        $accs_notification_usersoptions .= "\n" . '                    <option value="admin">' . 'Admin address' . ' (' . get_option('admin_email') . ')</option>';
    }
    $accs_notification_usersoptions .= "\n" . '                    <option value="other">' . 'Other' . '</option>';
    return $accs_notification_usersoptions;
}

// All sorts of validation on moderators, returning either an error or an array of moderators
function accs_notification_mod_array($accs_notification_mods, $accs_notification_add, $accs_notification_other_field)
{
    $accs_notification_return_mods = array();

    $i = 0;
    
    foreach ($accs_notification_mods as $accs_notification_mod) {
        
        // Check that it is a valid user
        if (is_numeric($accs_notification_mod)) {
            $accs_notification_validuser = get_userdata($accs_notification_mod);
            if (!$accs_notification_validuser) {
                return '**** ERROR: Invalid moderator user ID ****';
            }
            $accs_notification_return_mods[$i] = intval($accs_notification_mod);
        }
        
        // If it's a checkbox, we need the value of the dropdown list
        elseif ($accs_notification_mod == 'on') {

            // If the dropdown equals "other" then look for content in the "other" field, which had better be an e-mail address
            if ($accs_notification_add == 'other' && is_email($accs_notification_other_field)) {
                $accs_notification_return_mods[$i] = $accs_notification_other_field;
            }
            
            elseif (is_numeric($accs_notification_add)) {
                $accs_notification_validuser = get_userdata($accs_notification_add);
                if (!$accs_notification_validuser) {
                    return '**** ERROR: Invalid moderator user ID ****';
                }
                $accs_notification_return_mods[$i] = intval($accs_notification_add);
            }
            
            elseif ($accs_notification_add == 'admin') {
                $accs_notification_return_mods[$i] = $accs_notification_add;
            }
            
            else {
               return '**** ERROR: Invalid moderator e-mail address submitted ****';
            }
        }
        
        // Must be an e-mail address or admin
        elseif (is_email($accs_notification_mod) || $accs_notification_mod == 'admin') {
            $accs_notification_return_mods[$i] = $accs_notification_mod;
        }
        
        else {
            return '**** ERROR: Invalid e-mail address submitted ****';
        }
        ++$i;
    }
    return $accs_notification_return_mods;
}

// Processes changes to the moderator rules (who approves whose posts)
function accs_notification_modsubmit()
{
    global $wpdb, $accs_notification_db_group;
        
    // ----------------------------------
    // Process the default mod changes
    // ----------------------------------
    
    $accs_notification_defaultmods = $_POST['accs_notification_defaultmod']; // An array of default moderators (contains User IDs, "admin" or strictly e-mail addresses)
    $accs_notification_defaultmods_update = array();
    if ($accs_notification_defaultmods) {
        $accs_notification_defaultmods_update = accs_notification_mod_array($accs_notification_defaultmods, $_POST['adddefaultmod'], $_POST['accs_notification_defaultmodadd']);

        // Nicely scrubbed array of mods to serialize
        if (is_array($accs_notification_defaultmods_update)) {
            $accs_notification_defaultmod_serialized = serialize($accs_notification_defaultmods_update);
        }

        // It return an error
        else {
            return array( 'error', $accs_notification_process_close );
        }
        
        $accs_notification_defaultmodsuccess = $wpdb->query('UPDATE ' . $accs_notification_db_group . ' SET moderators = \'' . $accs_notification_defaultmod_serialized . '\' WHERE collabgroup = 1');
        
        if ($accs_notification_defaultmodsuccess) {
            return array( 'success',  'Default moderators updated.' );
        }
    }
    else {
        return array( 'error', 'You must have at least one default mod.' );
    }

    // We've made it this far, so nothing to report
    return false;
}

// This is the options page in the WordPress admin panel that enables you to set moderators on a per-user basis
function accs_notification_optionsmenu()
{
    if( isset( $_GET['delete_post_type_rule'] ) )
        ACCSNotificationEmails::accs_notification_delete_post_type_rule( $_GET['delete_post_type_rule'] );
    else
        accs_notification_mainoptionsmenu();
}

function accs_notification_mainoptionsmenu()
{
    global $wpdb, $accs_notification_db_group, $accs_notification_db_collabrules;
    
    $accs_notification_process_submit = '';

    if( isset( $_POST['accs_notification_modsubmit'] ) )
        $accs_notification_process_submit = accs_notification_modsubmit();
    elseif( isset( $_POST['accs_notification_post_type_submit'] ) )
        $accs_notification_process_submit = ACCSNotificationEmails::accs_notification_post_type_submit();
    elseif( isset( $_POST['accs_notification_add_post_type_submit'] ) )
        $accs_notification_process_submit = ACCSNotificationEmails::accs_notification_add_post_type_submit();
    
    // -----------------------------------
    // Get the list of default moderators
    // -----------------------------------
    
    $accs_notification_defaultmods_serialized = $wpdb->get_var('SELECT moderators FROM ' . $accs_notification_db_group . ' WHERE collabgroup = 1');
    
    // Put this list into an array since it is stored in the database as serialized
    $accs_notification_defaultmods = unserialize($accs_notification_defaultmods_serialized);

    // Build the list of options based on this array

    // Set up the default options variable
    $accs_notification_defaultoptions = '';

    // Whitespace!
    $accs_notification_defaultoptionswhitespace = '                ';

    // Establish a counter for the checkboxes
    $i = 0;

    $accs_notification_existingmods = array();
    
    foreach ($accs_notification_defaultmods as $accs_notification_defaultmod) {
        // If they've chosen a user ID, get the e-mail address associated with that user ID
        if (is_numeric($accs_notification_defaultmod)) {
            $accs_notification_userinfo = get_userdata($accs_notification_defaultmod);
            $accs_notification_defaultoptions .= "\n" . $accs_notification_defaultoptionswhitespace . '<p><input type="checkbox" name="accs_notification_defaultmod[' . $i . ']" value="' . $accs_notification_defaultmod . '" checked="checked" /> ' . $accs_notification_userinfo->display_name . ' (' . $accs_notification_userinfo->user_email . ')</p>';
            $accs_notification_existingmods[$accs_notification_defaultmod] = '';
        }

        // If they've chosen it to be the site admin, get the site admin e-mail address
        elseif ($accs_notification_defaultmod == 'admin') {
            $accs_notification_defaultoptions .= "\n" . $accs_notification_defaultoptionswhitespace  . '<p><input type="checkbox" name="accs_notification_defaultmod[' . $i . ']" value="' . $accs_notification_defaultmod . '" checked="checked" /> ' . sprintf( 'General admin (%s)', get_option( 'admin_email' ) ) . '</p>';
            $accs_notification_existingmods['admin'] = '';
        }
        
        // Whatever is left should be a custom e-mail address
        else {
            $accs_notification_defaultoptions .= "\n" . $accs_notification_defaultoptionswhitespace . '<p><input type="checkbox" name="accs_notification_defaultmod[' . $i . ']" value="' . $accs_notification_defaultmod . '" checked="checked" /> ' . $accs_notification_defaultmod . '</p>';
        }

        ++$i;
    }
    
    $accs_notification_defaultoptions .= "\n" . $accs_notification_defaultoptionswhitespace . '<p><input type="checkbox" name="accs_notification_defaultmod[' . $i .']" /> ' . 'Add:' . ' <select name="adddefaultmod" id="adddefaultmod">';
    $accs_notification_defaultoptions .= accs_notification_usersoptions( $accs_notification_existingmods );
    $accs_notification_defaultoptions .= "\n" . $accs_notification_defaultoptionswhitespace . '</select></p><p id="accs_notification_adddefaultmod">E-mail: <input type="text" name="accs_notification_defaultmodadd" width="30" maxlength="90" /></p>';
    
    // -----------------------------------
    // Get the post-type-specific moderator rules
    // -----------------------------------

    // Set up the default options variable
    $accs_notification_post_type_rules = '';

    $accs_notification_post_type_mods_results = $wpdb->get_results( 'SELECT rule_id, post_type, taxonomy, term, moderators FROM ' . $accs_notification_db_collabrules . ' ORDER BY post_type ASC, taxonomy ASC, term ASC', OBJECT );
    if( $accs_notification_post_type_mods_results )
    {
        $i_p = 0;
        
        foreach( $accs_notification_post_type_mods_results as $accs_notification_post_type_mods_result )
        {
            $accs_notification_post_type_rules .= '<tr>' . "\n";
            
            $accs_notification_rule_id = $accs_notification_post_type_mods_result ->rule_id;
            
            
            // Output the post type name
            $accs_notification_post_type_name = htmlspecialchars($accs_notification_post_type_mods_result->post_type, ENT_QUOTES );
            $accs_notification_post_type_rules .= '<td><p><strong>' . $accs_notification_post_type_name . '</strong> [<a href="?page=' . basename(__FILE__) . '&delete_post_type_rule=' . $accs_notification_rule_id. '">Delete</a>]</p></td>';

            // Output the post type taxonomy
            $accs_notification_post_type_taxonomy = htmlspecialchars( $accs_notification_post_type_mods_result->taxonomy, ENT_QUOTES );
            if( 'all' == $accs_notification_post_type_taxonomy )
            {
                $accs_notification_post_type_taxonomy_label = 'All';
            }
            else
            {
                $accs_notification_post_type_taxonomy_label = get_taxonomy( $accs_notification_post_type_taxonomy );
                if( '' == $accs_notification_post_type_taxonomy_label )
                {
                    $accs_notification_post_type_taxonomy_label =  '*** undefined ***';
                }
                else
                {
                    $accs_notification_post_type_taxonomy_label = $accs_notification_post_type_taxonomy_label->label;
                }
            }
            $accs_notification_post_type_rules .= '<td><p>' . $accs_notification_post_type_taxonomy_label . '</p></td>';
            
            $accs_notification_post_type_term = htmlspecialchars( $accs_notification_post_type_mods_result->term, ENT_QUOTES );
            // Output the post type term
            if( 'all' == $accs_notification_post_type_taxonomy )
            {
                $accs_notification_post_type_term = '*** n/a ***';
            }
            elseif( is_numeric( $accs_notification_post_type_term ) )
            {
                $accs_notification_post_type_term_object = get_term( $accs_notification_post_type_term, $accs_notification_post_type_taxonomy );
                if( $accs_notification_post_type_term_object && property_exists( $accs_notification_post_type_term_object, 'name' ) )
                {
                    $accs_notification_post_type_term = $accs_notification_post_type_term_object->name;
                }
            }
            $accs_notification_post_type_rules .= '<td><p>' . $accs_notification_post_type_term . '</p></td>';

            // Put this list of e-mail addresses an array since it is stored in the database as serialized
            $accs_notification_post_type_mods = unserialize( $accs_notification_post_type_mods_result->moderators );

            // Build the list of options based on this array
            // Establish a counter for the checkboxes
            $i = 0;
            
            $accs_notification_post_type_rules .= "\n" . '<td>';
            
            $accs_notification_existingmods = array();
            
            foreach( $accs_notification_post_type_mods as $accs_notification_post_type_mod )
            {
                // If they've chosen a user ID, get the e-mail address associated with that user ID
                if( is_int( $accs_notification_post_type_mod ) )
                {
                    $accs_notification_userinfo = get_userdata( $accs_notification_post_type_mod );
                    $accs_notification_post_type_rules .= "\n" . '<p><input type="checkbox" name="accs_notification_post_type_mod[' . $i_p . '][' . $i .']" value="' . $accs_notification_post_type_mod . '" checked="checked" /> ' . $accs_notification_userinfo->display_name . ' (' . $accs_notification_userinfo->user_email . ')</p>';
                    $accs_notification_existingmods[$accs_notification_post_type_mod] = '';
                }

                // If they've chosen it to be the site admin, get the site admin e-mail address
                elseif( 'admin' == $accs_notification_post_type_mod )
                {
                    $accs_notification_post_type_rules .= "\n" . '<p><input type="checkbox" name="accs_notification_post_type_mod[' . $i_p . '][' . $i .']" value="' . $accs_notification_post_type_mod . '" checked="checked" /> ' . 'General admin' . '(' . get_option('admin_email') . ')</p>';
                    $accs_notification_existingmods['admin'] = '';
                }
                
                // Whatever is left should be a custom e-mail address
                else
                {
                    $accs_notification_post_type_rules .= "\n" . '<p><input type="checkbox" name="accs_notification_post_type_mod[' . $i_p . '][' . $i .']" value="' . $accs_notification_post_type_mod . '" checked="checked" /> ' . $accs_notification_post_type_mod . '</p>';
                }
                
                ++$i;
            }
            
            $accs_notification_post_type_rules .= "\n" . '<p><input type="checkbox" name="accs_notification_post_type_mod[' . $i_p . '][' . $i .']" /> ' . 'Add:' . ' <select name="add_post_type_mod[' . $i_p . ']" id="post_type_mod_add[' . $i_p . ']">';
            $accs_notification_post_type_rules .= accs_notification_usersoptions( $accs_notification_existingmods );
            $accs_notification_post_type_rules .= "\n" . '</select></p><p id="accs_notification_post_type_mod_add[' . $i_p. ']">E-mail: <input type="text" name="accs_notification_post_type_mod_add[' . $i_p . ']" width="30" maxlength="90" /></p>';
            $accs_notification_post_type_rules .= "\n" . '<input type="hidden" name="accs_notification_rule_id[' . $i_p . ']" value="' . $accs_notification_rule_id . '" /></td>';
            $accs_notification_post_type_rules .= "\n" . '</tr>';
            ++$i_p;
        }
    }
    
?>
    <div class="wrap">
        <h2><?php print 'Manage notification e-mails'; ?></h2>
        <p><?php print 'Set the moderators who should be e-mailed whenever Contributor users submit pending posts.'; ?></p>
        <?php // 
        if( is_array( $accs_notification_process_submit ) && count( $accs_notification_process_submit ) )
        {
            print '<div id="message" class="updated fade">' . "\n";
            print $accs_notification_process_submit[1];
            print '</div>' . "\n";
        }
        ?>

        <h3><?php print 'Default moderators'; ?></h3>
        <form name="accs_notification_modform" action="<?php print '?page=' . basename(__FILE__); ?>" method="post">
        <p><?php print 'These users will be e-mailed if none of the rules below match. Note that they must be either editors or administrators.'; ?></p>
            <?php print $accs_notification_defaultoptions; ?>
            
        <p class="submit"><input type="submit" name="accs_notification_modsubmit" value="<?php print 'Update'; ?>" /></p>
        </form>
        
        <h3><?php print 'Moderators by post type and taxonomy'; ?></h3>
        <form name="accs_notification_post_type_form" action="<?php print '?page=' . basename(__FILE__); ?>" method="post">
        <h4><?php print 'Existing rules'; ?></h4>
        <table class="widefat">
            <tr>
                <th><?php print 'Post Type'; ?></th>
                <th><?php print 'Taxonomy'; ?></th>
                <th><?php print 'Term'; ?></th>
                <th><?php print 'Moderators'; ?></th>
            </tr>
            <?php print $accs_notification_post_type_rules; ?>
            
        </table>
        <p class="submit"><input type="submit" name="accs_notification_post_type_submit" value="<?php print 'Update'; ?>" /></p>
        </form>
        <form name="accs_notification_add_post_type_form" action="<?php print '?page=' . basename(__FILE__); ?>" method="post">
        <h4><?php print 'Add post-type-specific moderators'; ?></h4>
            <?php
            $post_types = get_post_types( '', 'objects');
            print 'Post type:' . ' <select name="post_types" id="post_types">';
            print '<option value="0">----------</option>';
            foreach( $post_types as $post_type )
            {
                // Don't show revisions, attachments, or navigation menu items, as they're not traditional posts
                if( ! in_array( $post_type->name, array( 'revision', 'attachment', 'nav_menu_item' ) ) )
                {
                    print '<option value="' . $post_type->name . '">' . $post_type->label . '</option>';
                }
            }
            print '</select><br /><br />';
            print 'Taxonomy:' . ' <select name="taxonomy_types" id="taxonomy_types">';
            print '</select><br /><br />';
            
            print 'Term:' . ' <select name="taxonomy_terms" id="taxonomy_terms">';
            print '</select>';
            //print '<input name="taxonomy_term" id="taxonomy_term" style="display: none;" type="text" width="30" maxlength="50" />';
            print '<p>' . 'Add moderator:' . ' <select name="add_post_type_rule_mod" id="post_type_rule_mod_add">';
            print '<option value="-1"></option>';
            print accs_notification_usersoptions( array() );
            print '</select></p><p id="accs_notification_post_type_rule_mod_add">E-mail: <input type="text" name="accs_notification_post_type_rule_mod_add" width="30" maxlength="90" /></p>';
            ?>
        <p class="submit"><input type="submit" name="accs_notification_add_post_type_submit" value="<?php print 'Update'; ?>" /></p>
        </form>        
    </div>

    <script type="text/javascript">
        jQuery( document ).ready( function()
        {
            // Functionality to hide the "Other" field as necessary
            if( jQuery( '#adddefaultmod' ).val() != 'other' )
            {
                jQuery( '#accs_notification_adddefaultmod' ).hide();
            }
            if( jQuery( '#groupmodadd' ).val() != 'other' )
            {
                jQuery( '#accs_notification_groupmodadd' ).hide();
            }
            if( jQuery( '#post_type_rule_mod_add' ).val() != 'other' )
            {
                jQuery( '#accs_notification_post_type_rule_mod_add' ).hide();
            }
            jQuery( '[id^=post_type_mod_add]' ).each( function()
            {
                var textareaID = '#accs_notification_' + jQuery( this ).attr( 'id' );
                textareaID = textareaID.replace("[", "\\[");
                textareaID = textareaID.replace("]", "\\]");
                if( jQuery( this ).val() != 'other' )
                {
                    jQuery( textareaID ).hide();
                }
            });
            jQuery( '[id^=usermodadd]' ).each( function()
            {
                var textareaID = '#accs_notification_' + jQuery( this ).attr( 'id' );
                textareaID = textareaID.replace("[", "\\[");
                textareaID = textareaID.replace("]", "\\]");
                if( jQuery( this ).val() != 'other' )
                {
                    jQuery( textareaID ).hide();
                }
            });
            jQuery( '#adddefaultmod' ).change( function()
            {
                addMod( jQuery( this ) );
            });
            jQuery( '#groupmodadd' ).change( function()
            {
                addMod( jQuery( this ) );
            });
            jQuery( '#post_type_rule_mod_add' ).change( function()
            {
                addMod( jQuery( this ) );
            });
            jQuery( '[id^=usermodadd]' ).change( function()
            {
                addMod( jQuery( this ) );
            });
            jQuery( '[id^=post_type_mod_add]' ).change( function()
            {
                addMod( jQuery( this ) );
            });
            
            // AJAX for post types
            jQuery( '#post_types' ).change( function()
            {
                var data = {
                        post_type: jQuery( this ).val(),
                        action: 'get_post_type_taxonomies'
                };
                
                jQuery( '#taxonomy_types' ).empty();
                jQuery( '#taxonomy_terms' ).empty();
                jQuery( '#taxonomy_term' ).val( '' );
                jQuery( '#taxonomy_terms' ).show();
                jQuery( '#taxonomy_term' ).hide();
                jQuery.post( ajaxurl, data, function( response )
                {
                    var taxonomies = jQuery.parseJSON( response );
                    if( '0' != taxonomies )
                    {
                        jQuery( '#taxonomy_types' ).append( '<option selected="selected" value="all">All</option>' );
                        jQuery.each( taxonomies, function( index, item )
                        {
                            jQuery( '#taxonomy_types' ).append( '<option value="' + item.name + '">' + item.label + '</option>' );
                        });
                    }
                });
            });
            jQuery( '#taxonomy_types' ).change( function()
            {
                var data = {
                        taxonomy: jQuery( this ).val(),
                        action: 'get_taxonomy_terms'
                };
                
                jQuery( '#taxonomy_terms' ).empty();
                jQuery.post( ajaxurl, data, function( response )
                {
                    var taxonomy_terms = jQuery.parseJSON( response );
                    if( '1' == taxonomy_terms )
                    {
                        jQuery( '#taxonomy_terms' ).hide();
                        jQuery( '#taxonomy_term' ).show();
                    }
                    else if( '0' != taxonomy_terms )
                    {
                        jQuery( '#taxonomy_terms' ).show();
                        jQuery( '#taxonomy_term' ).hide();
                        jQuery.each( taxonomy_terms, function( index, item )
                        {
                            jQuery( '#taxonomy_terms' ).append( '<option value="' + item.id + '">' + item.name + '</option>' );
                        });
                        jQuery( '#taxonomy_terms' ).append( '<option value="-1">--- Manual ---</option>' )
                    }
                });
            });
            jQuery( '#taxonomy_terms' ).change( function()
            {
                if( -1 == jQuery( this ).val() )
                {
                    jQuery( '#taxonomy_term' ).show();
                }
                else
                {
                    jQuery( '#taxonomy_term' ).val( '' );
                    jQuery( '#taxonomy_term' ).hide();
                }
            });
        });
        function addMod( htmlElement )
        {
            // Escape selectors for jQuery
            var textareaID = '#accs_notification_' + jQuery( htmlElement ).attr( 'id' );
            textareaID = textareaID.replace("[", "\\[");
            textareaID = textareaID.replace("]", "\\]");
            if( 'other' == jQuery( htmlElement ).val() )
            {
                jQuery( textareaID ).show();
            }
            else
            {
                jQuery( textareaID ).hide();
            }
        }
        
    </script>
<?php
}

// This class should eventually hold all helper functions
class ACCSNotificationEmails
{

    // Ajax function to return JSON-encoded taxonomies for a given post type
    function accs_notification_get_post_type_taxonomies()
    {
        $post_type = $_POST['post_type'];
        if( post_type_exists( $post_type ) )
        {
            $taxonomies = get_taxonomies( array(), 'objects' );
            if( $taxonomies )
            {
                $taxonomy_array = array();
                foreach( $taxonomies as $taxonomy )
                {
                    // Skip a few built-in taxonomy types for now, as we're not going to support them
                    if( ! in_array( $taxonomy->name, array( 'nav_menu', 'link_category', 'post_format' ) ) )
                    {
                        if( '' == $taxonomy->label )
                        {
                            $taxonomy_label = $taxonomy->name;
                        }
                        else
                        {
                            $taxonomy_label = $taxonomy->label;
                        }
                        
                        $taxonomy_array[] = array( 'name' => $taxonomy->name,
                                                   'label' => $taxonomy_label );
                    }
                }
                print json_encode( $taxonomy_array );
                die();
            }
        }
        print '0';
        die();
    }

    // Ajax function to return JSON-encoded terms for a given taxonomy
    function accs_notification_get_taxonomy_terms()
    {
        $taxonomy = $_POST['taxonomy'];
        if( taxonomy_exists( $taxonomy ) )
        {
            $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
            if( $terms )
            {
                $terms_array = array();
                foreach( $terms as $term )
                {
                    $terms_array[] = array( 'id' => $term->term_id, 'name' => $term->name );
                }
                print json_encode( $terms_array );
                die();
            }
            else
            {
                print '1';
                die();
            }
        }
        print '0';
        die();
    }
    
    function accs_notification_add_post_type_submit()
    {
        global $wpdb, $accs_notification_db_collabrules;

        // ----------------------------------
        // Process a new post type rule submission
        // ----------------------------------

        if( -1 != $_POST['add_post_type_rule_mod'] )
        {
            $post_type = $_POST['post_types'];
            $taxonomy_type = $_POST['taxonomy_types'];
            if( '' != trim( $_POST['taxonomy_term'] ) )
            {
                $taxonomy_term = trim( $_POST['taxonomy_term'] );
            }
            elseif( 'all' == $taxonomy_type )
            {
                $taxonomy_term = '';
            }
            else
            {
                $taxonomy_term = $_POST['taxonomy_terms'];
            }
            
            $post_type_mod = $_POST['add_post_type_rule_mod'];

            // Check: Is this taxonomy available for this post type?
            $post_type_taxonomies = get_taxonomies( array(), 'names' );
            if( ! in_array( $taxonomy_type, $post_type_taxonomies ) && 'all' != $taxonomy_type )
            {
                return array( 'error', '**** ERROR: That taxonomy type does not exist for that post type ****' );
            }
            
            // No check if taxonomy term is available for this taxonomy because you can often have freeform terms
            $taxonomy_term = substr( $taxonomy_term, 0, 255 );
            
            // Check to make sure that this rule doesn't already exist with the same post type, taxonomy type, and taxonomy term
            // It might still exist if you had first submitted the term freeform and now you're submitting after the term was officially added and vice versa
            // Possible TODO: Check for both the ID and the text version of the term
            $rule_exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $accs_notification_db_collabrules
                                                            WHERE post_type = %s
                                                            AND taxonomy = %s
                                                            AND term = %s;"
                                                            , $post_type, $taxonomy_type, $taxonomy_term
                                                         ) );
            if( $rule_exists )
            {
                return array( 'error', '**** ERROR: That post type rule already exists. Please add or remove moderators to the existing rule. ****');
            }
            
            // Check the added moderator (admin, user ID, or e-mail address)
            // Check that it is a valid user
            if( is_numeric( $post_type_mod ) )
            {
                $accs_notification_validuser = get_userdata( $post_type_mod );
                if( !$accs_notification_validuser )
                {
                    return array( 'error', '**** ERROR: Invalid new moderator user ID ****');
                }
                $post_type_mod = intval( $post_type_mod );
            }
                
            // If the dropdown equals "other" then look for content in accs_notification_post_type_rule_mod_add, which had better be an e-mail address
            elseif( 'other' == $post_type_mod && is_email( $_POST['accs_notification_post_type_rule_mod_add'] ) )
            {
                $post_type_mod = $_POST['accs_notification_post_type_rule_mod_add'];
            }
            elseif( 'admin' != $post_type_mod )
            {
                return array( 'error', '**** ERROR: Invalid new moderator submitted ****');
            }

            $post_type_mod_serialized = serialize( array( $post_type_mod ) );
            $accs_notification_add_post_type_mod_success = $wpdb->insert(
                $accs_notification_db_collabrules,
                array(   'post_type'  => $post_type
                       , 'taxonomy'   => $taxonomy_type
                       , 'term'       => $taxonomy_term
                       , 'moderators' => $post_type_mod_serialized
                      )
                );

            if( $accs_notification_add_post_type_mod_success )
            {
                return array( 'success', sprintf( 'New moderator added for the post type rule.' ) );
            }
            else
            {
                return array( 'error', '**** ERROR: Unknown query error when adding a new moderator for the post type rule ****' );
            }
        }
        
        else
        {
            return array( 'error', '**** ERROR: No moderator was submitted for the post type rule ****' );
        }

        // We've made it this far, so nothing to do!
        return false;
    }
    
    // Edit post type moderators
    function accs_notification_post_type_submit()
    {
        global $wpdb, $accs_notification_db_collabrules;

        // ----------------------------------
        // Process the post-type-specific moderator changes
        // ----------------------------------
        
        $updated = false;
        $accs_notification_post_type_mods = $_POST['accs_notification_post_type_mod']; // An array of moderators for each post type rule (contains User IDs, "admin" or strictly e-mail addresses)
        $accs_notification_rule_ids = $_POST['accs_notification_rule_id']; // An array of post type rules to be updated
        $accs_notification_num_submits = array_keys( $accs_notification_rule_ids );

        if( $accs_notification_num_submits )
        {
            foreach( $accs_notification_num_submits as $accs_notification_num_submit )
            {
                $accs_notification_post_type_mod = $accs_notification_post_type_mods[$accs_notification_num_submit];
                $accs_notification_rule_id = intval( $accs_notification_rule_ids[$accs_notification_num_submit] );
                
                // Does this post type rule exist?
                $post_type_rule_exists = ACCSNotificationEmails::post_type_rule_exists( $accs_notification_rule_id );
                
                if( ! $post_type_rule_exists )
                {
                    return array( 'error', sprintf('**** ERROR: Post type rule with ID of %d does not exist ****', $accs_notification_rule_id ) );
                }
                if( $accs_notification_post_type_mod )
                {
                    $accs_notification_post_type_mod_update = accs_notification_mod_array( $accs_notification_post_type_mod, $_POST['add_post_type_mod'][$accs_notification_num_submit], $_POST['accs_notification_post_type_mod_add'][$accs_notification_num_submit] );

                    // Nicely scrubbed array of mods to serialize
                    if( is_array( $accs_notification_post_type_mod_update ) )
                    {
                        $accs_notification_post_type_mod_serialized = serialize( $accs_notification_post_type_mod_update );
                    }
                    // It returns an error
                    else
                    {
                        return array( 'error', $accs_notification_post_type_mod_update );
                    }
                    
                    $accs_notification_post_type_mod_success = $wpdb->update(
                                                                $accs_notification_db_collabrules
                                                                , array( 'moderators' => $accs_notification_post_type_mod_serialized )
                                                                , array( 'rule_id' => $accs_notification_rule_id )
                                                               );
                    if( $accs_notification_post_type_mod_success )
                    {
                        $updated = true;
                    }
                }
                else
                {
                    return array( 'error', 'You must have at least one default moderator for each rule. Otherwise, delete the rule.' );
                }
            }
        }
        
        // We've made it this far, so success!
        if( $updated )
        {
            return array( 'success', 'Moderators for the post type rules updated.');
        }
        else
        {
            return false;
        }
    }
    
    function accs_notification_delete_post_type_rule( $rule_id )
    {
        global $wpdb, $accs_notification_db_collabrules;
        $rule_id = intval( $rule_id );

        print '<div class="wrap">';
        print '<h2>' . 'Delete post type rule' . '</h2>';

        if( ACCSNotificationEmails::post_type_rule_exists( $rule_id ) )
        {                
            // If they actually wanted to delete the moderators for this category, let them know the result
            if( isset( $_POST['accs_notification_delete_post_type_rule_yes'] ) )
            {
                $wpdb->query( 'DELETE FROM ' . $accs_notification_db_collabrules . ' WHERE rule_id = ' . $rule_id . ' LIMIT 1' );
                print "\n" . '<p>' . sprintf( 'Post type rule successfully deleted.');
                print "\n" . '<p><a href="?page=' . basename(__FILE__) . '">Back</a></p>' . "\n";
            }
            else
            {
                print "\n" . '<p>' . 'Are you sure you want to remove this post type rule?' . '</p>';
                print "\n" . '<form method="post" action="?page=' . basename(__FILE__) . '&delete_post_type_rule=' . $rule_id . '">';
                print "\n" . '<p class="submit"><input type="submit" name="accs_notification_delete_post_type_rule_yes" value="' . 'Yes' . '" /></p>';
                print "\n" . '</form>';
                print "\n" . '<form method="post" action="?page=' . basename(__FILE__) . '">';
                print "\n" . '<p class="submit"><input type="submit" value="' . 'No, go back' . '" /></p>';
                print "\n" . '</form>';
            }
        }
        else
        {
            print '<p>' . 'That post type rule does not exist.' . '</p>';
            print '<p><a href="?page=' . basename(__FILE__) . '">Back</a></p>' . "\n";
        }
        print '</div>';
    }
    
    function post_type_rule_exists( $rule_id )
    {
        global $wpdb, $accs_notification_db_collabrules;
        
        $exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $accs_notification_db_collabrules
                                                            WHERE rule_id = %d"
                                                            , intval( $rule_id )
                                                         ) );
        return $exists;
    }
    
}

function accs_notification_addoptionsmenu()
{
    global $accs_notification_required_capability;
    add_options_page( 'ACCS Notification e-mails', 'ACCS Notification e-mails', $accs_notification_required_capability, basename( __FILE__ ), 'accs_notification_optionsmenu' );
}

/* --------------------------------------------
Helper functions
-----------------------------------------------*/

//--------------------------------------------
//Add meta box
//---------------------------------------------

function accs_note_add_meta_box()
{
    global $accs_note_post_types;
    foreach( $accs_note_post_types as $accs_note_post_type )
        add_meta_box('collaboration', 'Notes', 'accs_note_meta_contents', $accs_note_post_type, 'side', 'high');
}

//--------------------------------------------
//Output within meta box
//---------------------------------------------

function accs_note_meta_contents()
{
    global $accs_saved_note;
    ?>
    <div id="accs_note_add_post_note" style="margin: 10px 0 10px 0;"><label for="accs_note_post_note">Send note with notification Email:</label><br /><textarea rows="3" cols="30" name="accs_note_post_note" id="accs_note_post_note" style="width: 99%"></textarea></div>
    <?php
    //Deny button
    if ( current_user_can('edit_others_posts') && get_post($_GET['post'], 'object')->post_status == 'pending' )
    {
       
        $id = $_GET['post'];
        echo "<a href='post.php?post=$id&deny&action=edit' class='save-post-status button-primary'>"
        
        ?>
            <?php esc_attr_e('Deny') ?>
<!--            <input name="save" type="submit" class="button-primary" id="draft" value="<?php esc_attr_e('Deny') ?>"/>-->
        </a>
        <?php
    }
}

// Change the admin area wp-admin/edit.php if current user is admin or editor
function deny_status()
{
    $post = get_post($_GET['post'], 'object');
    // If current user is admin or editor
    if(current_user_can('edit_others_posts'))
    {
        if(isset($_GET['deny']))
        {
            $post->post_status = 'draft';
            wp_update_post($post);
        }			
    }
}

// If a note was submitted, we will use it in the e-mails
function refresh_note()
{
    global $accs_saved_note;
    if (isset($_POST['accs_note_post_note']) && $_POST['accs_note_post_note'] != '')
        $accs_saved_note = stripslashes( $_POST['accs_note_post_note'] );
}

//add_action( 'init', 'refresh_note', 1);
add_filter( 'init', 'deny_status');
add_filter( 'transition_post_status', 'accs_notification_pending',1,3);

add_action( 'admin_print_scripts', 'accs_notification_js_admin_header' );
add_action( 'admin_menu','accs_notification_addoptionsmenu',1);
add_action( 'wp_ajax_get_post_type_taxonomies', array( 'ACCSNotificationEmails', 'accs_notification_get_post_type_taxonomies' ) );
add_action( 'wp_ajax_get_taxonomy_terms', array( 'ACCSNotificationEmails', 'accs_notification_get_taxonomy_terms' ) );

add_action( 'admin_menu', 'accs_note_add_meta_box' );

} // This closes that initial check to make sure someone is actually logged in
?>